import { Parameter } from '../sql';
import { Connection, ISOLATION_LEVEL } from './connection';
import { Executor } from './executor';
import { Pool } from './pool';
import { Sqlifier } from './sqlifier';
import { QueryResult } from './types';

// export interface ExecutorWithTrans extends Executor {
//   trans<T>(
//     handler: (abort: (message?: string) => void) => Promise<T>,
//     isolationLevel?: ISOLATION_LEVEL
//   ): Promise<T>;
// }

/**
 * 全局执行器
 */
export class PoolExecutor extends Executor {
  constructor(private readonly pool: Pool) {
    super();
  }

  async trans<T>(
    handler: (
      connection: Connection,
      abort: (message?: string) => void
    ) => Promise<T>,
    isolationLevel?: ISOLATION_LEVEL
  ): Promise<T> {
    const connection = await this.pool.acquire();
    try {
      const res = await connection.trans(abort => {
        return handler(connection, abort);
      }, isolationLevel);
      return res;
    } finally {
      this.pool.release(connection);
    }
  }

  protected async doQuery(
    sql: string,
    params?: Parameter<any, string>[]
  ): Promise<QueryResult<any, any, any>> {
    const connection = await this.pool.acquire();
    try {
      const res = await connection['doQuery'](sql, params);
      return res;
    } finally {
      this.pool.release(connection);
    }
  }

  protected get sqlifier(): Sqlifier {
    return this.pool.provider.sqlifier;
  }
}
